

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <fcntl.h>

#include "common.h"
#include "mthread.h"

using namespace std;

#ifdef DEBUG
extern pthread_mutex_t mtx;
#endif

void log(char* fmt, ...) {
	char* wr;
	va_list ap;
	int fd;
	
	va_start(ap, fmt);
	vasprintf(&wr, fmt, ap);
	pthread_mutex_lock(&mtx);
	fd = open("/dev/null", O_APPEND|O_RDWR|O_CREAT|O_SYNC);
	write(fd, wr, strlen(wr));
	free(wr);
	close(fd);
	sync();
	pthread_mutex_unlock(&mtx);
}

void mtworker(void* arg) {
	int vp = (int64_t)arg; 
	mt_thread_t th = mt_thread_self(vp); 
	char* ccc;
	for(int j = 0; j < 8; j++) {
		
#ifdef DEBUG
		asprintf(&ccc, "%i %i\n", j, &j);
		//log("dbglog %s %i", ccc, strcmp("asdad", ccc));
		printf("CPU: %i THREAD: %i LOOP: %i\n", vp, th->ID, j);
		free(ccc);
#endif		
		_MT_SWITCH_CONTEXT(th, vp);
	}
	return;
}

void* pworker(void* xxx) {
	int arg = (int64_t)xxx;
	int vp = vp_init(arg);
	mt_thread_t th = mt_thread_self(vp); 
	//while(1) {
		for(int i = 0; i < 512; i++) {
			mt_thread_create(mtworker, (void*)vp, 0, 32*1024, vp);
			_MT_SWITCH_CONTEXT(th, vp);
		}
	
		log("joining cpu %i\n", vp);
		mt_join_all(vp);
	//}
	log("vp_destr on cpu %i\n", vp);
	vp_destroy(vp);
	printf("CPU: %i Halting\n", vp);
	log("halting cpu %i\n", vp);	
	//pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
	/*while(1) {pworker(NULL);};
	return EXIT_SUCCESS;*/
	
	pthread_t pt[128];
	pthread_attr_t pta[128];

	while(true) {
		for(int i = 0; i < 16; i++) {
			cout << "starting new cpu "<< i <<"\n";
			pthread_attr_init(&pta[i]);
			pthread_attr_setstacksize(&pta[i], 1024*16);
			pthread_create(&pt[i], &pta[i], pworker, (void*)i);
			
		}
	
		for(int i = 0; i < 16; i++) {
			pthread_join(pt[i], NULL);
		}
		
	}
	
  	return EXIT_SUCCESS;
}
